#include <assert.h>
#include <ctype.h>
#include <locale.h>
#include <errno.h>
#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/*
用于编写函数指针的助记符
A mnemonic for writing a function pointer definition is the following procedure:
1. Begin by writing a normal function declaration: returnType name(parameters)
2. Wrap the function name with pointer syntax: returnType (*name)(parameters)

int (*fp)(int); // declare a function pointer
*/


/* increment: take number, increment it by one, and return it */
int increment(int i)
{
    printf("***** increment *****\n");
    printf("increment %d by 1\n", i);
    return i + 1;
}

/* decrement: take number, decrement it by one, and return it */
int decrement(int i)
{
    printf("***** decrement *****\n");
    printf("decrement %d by 1\n", i);
    return i - 1;
}

// typedef command to save you some typing, and to make the code more clear:
typedef int (*ptrInt)(int, int);

int Add(int i, int j){
    return i+j;
}
int Multiply(int i, int j){
    return i*j;
}

/*
You can also create **an Array of function-pointers**. 
If all the pointers are of the same "structure":

*/

void array_function_pointer(void)
{
    printf("***** array_function_pointer *****\n");
    int (*array[2])(int x , int y); // can hold 2 function pointers
    array[0] = Add;
    array[1] = Multiply;
    for (int i=0; i<2;i++)
    {
        printf("array[%d](1,2): %d\n", i, array[i](1,2));
    }
}

void main(void)
{
    int num = 0; /* declare number to increment */
    int (*fp)(int); /* declare a function pointer */
    fp = &increment; /* set function pointer to increment function */
    num = (*fp)(num); /* increment num */
    num = (*fp)(num); /* increment num a second time */
    fp = &decrement; /* set function pointer to decrement function */
    num = (*fp)(num); /* decrement num */
    printf("num is now: %d\n", num);

    ptrInt ptr1 = Add;
    ptrInt ptr2 = Multiply;
    printf("%d\n", (*ptr1)(2,3)); //will print 5
    printf("%d\n", (*ptr2)(2,3)); //will print 6

    array_function_pointer();
    system("pause");
}